require 'active_record'

module Zepho
  module Acts #:nodoc:
    module SimplyRichAssociation #:nodoc:

      def self.included(mod)
        mod.extend(ClassMethods)
      end

      # declare the class level helper methods which
      # will load the relevant instance methods
      # defined below when invoked
      module ClassMethods
        def has_many_through(other_table, join_table)
          has_many join_table.to_sym
          has_many other_table.to_sym, :through => join_table.to_sym
        end

        def has_self_referential_many_to_many(child_table)

          child = child_table.to_s
          c = child.singularize 

          has_and_belongs_to_many child.to_sym, 
                                  :class_name => self.name, 
                                  :join_table => child + '_' + self.name.pluralize, 
                                  :association_foreign_key => c + "_id", 
                                  :foreign_key => self.name + "_id", 
                                  :after_add => :create_bidirectional_link, 
                                  :after_remove => :remove_bidirectional_link 

          class_eval do
            define_method("create_bidirectional_link") do |c|
              c.send(child) << self unless c.send(child).include?(self) 
            end

            define_method("remove_bidirectional_link") do |c|
              c.send(child).delete(self) rescue nil 
            end                                  
          end

        end
      end
    end

    # reopen ActiveRecord and include all the above to make
    # them available to all our models if they want it

    ActiveRecord::Base.class_eval do
      include Zepho::Acts::SimplyRichAssociation
    end